package design.onekey.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import design.onekey.base.BaseEntity;
import design.onekey.base.PageEntity;
import design.onekey.constant.StatusCode;
import design.onekey.model.dto.UserInfoDto;
import design.onekey.exception.BizException;
import design.onekey.mapper.UserRoleMapper;
import design.onekey.model.SysOrg;
import design.onekey.model.UserRole;
import design.onekey.model.UserRoleFunction;
import design.onekey.model.UserRoleMenu;
import design.onekey.model.dto.UserRoleDto;
import design.onekey.service.ISysOrgService;
import design.onekey.service.IUserRoleFunctionService;
import design.onekey.service.IUserRoleMenuService;
import design.onekey.service.IUserRoleService;
import design.onekey.util.MessageUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

/**
* @Description: UserRole服务实现
* @author
* @date 2020-06-05 04:03:38
* @version V1.0
*/
@Service
public class UserRoleServiceImpl extends ServiceImpl<UserRoleMapper, UserRole> implements IUserRoleService {


    /**
     * @Fields iSysOrgService : 组织服务注入
     * @author blcloak
     * @date 2020-06-10 10:03:05
     */
    @Autowired
    private ISysOrgService iSysOrgService;

    /**
     * @Fields iUserRoleMenuService : 角色菜单服务注入
     * @author blcloak
     * @date 2020-06-11 02:35:43
     */
    @Autowired
    private IUserRoleMenuService iUserRoleMenuService;

    /**
     * @Fields iUserRoleFunctionService : 角色功能服务注入
     * @author blcloak
     * @date 2020-06-11 02:35:58
     */
    @Autowired
    private IUserRoleFunctionService iUserRoleFunctionService;


    /**
     * @Title: tablePagingQuery
     * @Description: 表格分页查询
     * @param @param model
     * @return BaseEntity
     * @author
     * @throws
     */
    @Override
    public PageEntity tablePagingQuery(UserRole model) {
        PageEntity result = new PageEntity();
        model.setDelFlag(1);
        com.github.pagehelper.Page<?> page = PageHelper.startPage(model.getCurrentPage(), model.getPageSize()); //分页条件
        List<UserRole> list = this.baseMapper.searchDataLike(model);
        result.setData(list);
        result.setTotal(page.getTotal());
        result.setCurrentPage(model.getCurrentPage());
        result.setPageSize(model.getPageSize());
        return result;
    }

    /**
     * @Title: getTableList
     * @Description: 获取表格数据
     * @param model
     * @param userInfoDto
     * @return
     * @author blcloak
     * @date 2020-06-10 09:32:45
     */
    @Override
    public PageEntity getTableList(UserRoleDto model, UserInfoDto userInfoDto) {
        PageEntity result = new PageEntity();
        model.setDelFlag(1);
        com.github.pagehelper.Page<?> page = PageHelper.startPage(model.getCurrentPage(), model.getPageSize()); //分页条件
        if (1 != userInfoDto.getIsAdmin()) {
            //非超级管理员只能看到自己组织下的数据
            HashSet<Long> rids = new HashSet<>();
            Long orgId = userInfoDto.getOrgId();
            List<Long> orgIds = new ArrayList<Long>();
            orgIds.add(orgId);
            iSysOrgService.loadAllOrgByIds(orgIds,rids);
            model.setOrgIds(new ArrayList<Long>(rids));
        }
        List<UserRoleDto> list = this.baseMapper.getTableList(model);
        result.setData(list);
        result.setTotal(page.getTotal());
        result.setCurrentPage(model.getCurrentPage());
        result.setPageSize(model.getPageSize());
        return result;
    }


    /**
     *<p>Title: getDetail</p>
     *<p>Description: 获取详情</p>
     * @author
     * @param id
     * @return
     */
    @Override
    public BaseEntity getDetail(Long id) {
        UserRoleDto userRoleDto = new UserRoleDto();
        //获取角色信息
        UserRole userRole = this.getById(id);
        BeanUtils.copyProperties(userRole, userRoleDto);
        //获取组织信息
        SysOrg sysOrg = iSysOrgService.getById(userRole.getOrgId());
        if (sysOrg != null) {
            userRoleDto.setOrgName(sysOrg.getOrgName());
        }
        return userRoleDto;
    }

    /**
     *<p>Title: insert</p>
     *<p>Description: 新增数据</p>
     * @author
     * @param model
     * @return
     */
    @Transactional
    @Override
    public BaseEntity insert(UserRole model,UserInfoDto userInfoDto) {
        BaseEntity result = new BaseEntity();
        //判断roleCode是否存在
        QueryWrapper<UserRole> queryWrapper = new QueryWrapper<UserRole>();
        if (1 == userInfoDto.getIsAdmin()) {
            //超级管理员，则使用前台传过来的orgId
            if (model.getOrgId() == null) {
                throw new BizException(StatusCode.CHECK_FAILURE, MessageUtil.getValue("error.notnull", new String[] {"组织信息"}));
            }
            queryWrapper.in("org_id", model.getOrgId());
        }else {
            //非超级管理员，使用当前登录用户的orgId
            queryWrapper.eq("org_id", userInfoDto.getOrgId());
        }
        queryWrapper.eq("user_role_code", model.getUserRoleCode());
        queryWrapper.eq("del_flag", 1);
        UserRole userRole = this.getOne(queryWrapper);
        if (userRole != null) {
            throw new BizException(StatusCode.FAILURE, MessageUtil.getValue("error.check.exist", new String[] {"角色代码"}));
        }
        this.save(model);
        result.setStatusMsg(MessageUtil.getValue("info.insert"));
        return result;
    }

    /**
     *<p>Title: update</p>
     *<p>Description: 更新数据</p>
     * @author
     * @param model
     * @return
     */
    @Transactional
    @Override
    public BaseEntity update(UserRole model, UserInfoDto userInfoDto) {
        BaseEntity result = new BaseEntity();
        //判断roleCode是否存在
        QueryWrapper<UserRole> queryWrapper = new QueryWrapper<UserRole>();
        if (1 == userInfoDto.getIsAdmin()) {
            //超级管理员，则使用前台传过来的orgId
            if (model.getOrgId() == null) {
                throw new BizException(StatusCode.CHECK_FAILURE, MessageUtil.getValue("error.notnull", new String[] {"组织信息"}));
            }
            queryWrapper.in("org_id", model.getOrgId());
        }else {
            //非超级管理员，使用当前登录用户的orgId
            queryWrapper.eq("org_id", userInfoDto.getOrgId());
        }
        queryWrapper.ne("id", model.getId());
        queryWrapper.eq("user_role_code", model.getUserRoleCode());
        queryWrapper.eq("del_flag", 1);
        UserRole userRole = this.getOne(queryWrapper);
        if (userRole != null) {
            throw new BizException(StatusCode.FAILURE, MessageUtil.getValue("error.check.exist", new String[] {"角色代码"}));
        }
        this.updateById(model);
        result.setStatusMsg(MessageUtil.getValue("info.update"));
        return result;
    }

    /**
     *<p>Title: delete</p>
     *<p>Description: 单条删除数据</p>
     * @author
     * @param model
     * @return
     */
    @Transactional
    @Override
    public BaseEntity delete(Long id) {
        UserRole userRole = new UserRole();
        userRole.setId(id);
        userRole.setDelFlag(2);
        this.updateById(userRole);
        BaseEntity result = new BaseEntity();
        result.setStatusMsg(MessageUtil.getValue("info.delete"));
        return result;
    }

    /**
     *<p>Title: deleteBatch</p>
     *<p>Description: 批量删除数据</p>
     * @author
     * @param list
     * @return
     */
    @Transactional
    @Override
    public BaseEntity deleteBatch(List<Long> ids) {
        List<UserRole> list = new ArrayList<UserRole>();
        for (int i = 0; i < ids.size(); i++) {
            UserRole userRole = new UserRole();
            userRole.setId(ids.get(i));
            userRole.setDelFlag(2);
            list.add(userRole);
        }
        BaseEntity result = new BaseEntity();
        if (list != null && list.size() > 0) {
            this.updateBatchById(list);
        }
        result.setStatusMsg(MessageUtil.getValue("info.delete"));
        return result;
    }

    /**
     * @Title: getUserRole
     * @Description:根据用户id获取角色信息
     * @param userId
     * @return
     * @author blcloak
     * @date 2020-06-05 05:23:50
     */
    @Override
    public UserRole getUserRole(Long userId) {

        return this.baseMapper.getUserRole(userId);
    }


    /**
     * @Title: getOrgRoles
     * @Description: 获取组织下对应的角色
     * @param userRole
     * @return
     * @author blcloak
     * @date 2020-06-09 06:27:42
     */
    @Override
    public List<UserRole> getOrgRoles(UserRoleDto userRole) {
        QueryWrapper<UserRole> queryWrapper = new QueryWrapper<UserRole>();
        queryWrapper.in("org_id", userRole.getOrgIds());
        queryWrapper.eq("del_flag", 1);
        List<UserRole> result = this.list(queryWrapper);
        return result;
    }

   /**
    * @Title: authed
    * @Description: 角色授权
    * @param userRoleDto
    * @return
    * @author blcloak
    * @date 2020-06-11 02:20:56
    */
   @Override
   @Transactional
   public BaseEntity authed(UserRoleDto userRoleDto) {
       BaseEntity result = new BaseEntity();
       //获取当前用户的菜单权限和功能权限
       QueryWrapper<UserRoleMenu> menuQueryWrapper = new QueryWrapper<UserRoleMenu>();
       menuQueryWrapper.eq("role_id", userRoleDto.getId());
       menuQueryWrapper.eq("del_flag", 1);
       List<UserRoleMenu> menus = iUserRoleMenuService.list(menuQueryWrapper);
       QueryWrapper<UserRoleFunction> functionWrapper = new QueryWrapper<UserRoleFunction>();
       functionWrapper.eq("role_id", userRoleDto.getId());
       functionWrapper.eq("del_flag", 1);
       List<UserRoleFunction> functions = iUserRoleFunctionService.list(functionWrapper);
       List<String> userAuth = new ArrayList<String>();//用户当前拥有的权限
       if (menus != null && menus.size() > 0) {
           for (int i = 0; i < menus.size(); i++) {
               userAuth.add(String.valueOf(menus.get(i).getMenuId()));
           }
       }
       if (functions != null && functions.size() > 0) {
           for (int i = 0; i < functions.size(); i++) {
               userAuth.add("api-"+ functions.get(i).getFunctionId());
           }
       }
       //用户拥有的权限和新授权的权限对比，得到需要添加和删除的权限
       List<String> addData = this.getDiffData(userRoleDto.getAuthed(), userAuth);//需要添加的权限
       List<String> delData = this.getDiffData(userAuth, userRoleDto.getAuthed());//需要删除的权限
       if (delData != null && delData.size() > 0) {
           for (int i = 0; i < delData.size(); i++) {
               if (delData.get(i).contains("api-")) {//功能
                   UpdateWrapper<UserRoleFunction> updateWrapper = new UpdateWrapper<UserRoleFunction>();
                   updateWrapper.eq("role_id", userRoleDto.getId());
                   updateWrapper.eq("function_id", delData.get(i).split("-")[1]);
                   UserRoleFunction userRoleFunction = new UserRoleFunction();
                   userRoleFunction.setDelFlag(2);
                   this.iUserRoleFunctionService.update(userRoleFunction, updateWrapper);
               }else {//菜单
                   if (!delData.get(i).contains("menu")) {
                       UpdateWrapper<UserRoleMenu> updateWrapper = new UpdateWrapper<UserRoleMenu>();
                       updateWrapper.eq("role_id", userRoleDto.getId());
                       updateWrapper.eq("menu_id", delData.get(i));
                       UserRoleMenu userRoleMenu = new UserRoleMenu();
                       userRoleMenu.setDelFlag(2);
                       this.iUserRoleMenuService.update(userRoleMenu,updateWrapper);
                   }

               }
           }
       }
       List<UserRoleFunction> addFunctions = new ArrayList<UserRoleFunction>();
       List<UserRoleMenu> addMenus = new ArrayList<UserRoleMenu>();
       if (addData != null && addData.size()>0) {
           for (int i = 0; i < addData.size(); i++) {
               if (addData.get(i).contains("api-")) {//功能
                   UserRoleFunction userRoleFunction = new UserRoleFunction();
                   userRoleFunction.setRoleId(userRoleDto.getId());
                   userRoleFunction.setFunctionId(Long.valueOf(addData.get(i).split("-")[1]));
                   addFunctions.add(userRoleFunction);
               }else {//菜单
                   if (!addData.get(i).contains("menu")) {
                       UserRoleMenu userRoleMenu = new UserRoleMenu();
                       userRoleMenu.setRoleId(userRoleDto.getId());
                       userRoleMenu.setMenuId(Long.valueOf(addData.get(i)));
                       addMenus.add(userRoleMenu);
                   }

               }
           }
       }
       if (addFunctions != null && addFunctions.size() > 0) {
           this.iUserRoleFunctionService.saveBatch(addFunctions);
       }
       if (addMenus != null && addMenus.size() > 0) {
           this.iUserRoleMenuService.saveBatch(addMenus);
       }
       result.setStatusMsg(MessageUtil.getValue("info.role.auth"));
       return result;
   }



    /**
     * @Title: getDiffData
     * @Description: 获取集合差值
     * @param list1
     * @param list2
     * @return
     * @author blcloak
     * @date 2020-06-11 02:55:49
     */
    private List<String> getDiffData(List<String> list1,List<String> list2)
    {
        List<String> newlist1 = new ArrayList<String>();
        newlist1.addAll(list1);
        List<String> newlist2 = new ArrayList<String>();
        newlist2.addAll(list2);
        newlist1.removeAll(newlist2);
        return newlist1;
    }

}
